home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / Managed / Direct3D / CustomUI / CustomUI.cs next >
Encoding:
Text File  |  2004-09-28  |  31.3 KB  |  637 lines

  1. //-----------------------------------------------------------------------------
  2. // File: CustomUI.cs
  3. //
  4. // Starting point for new Direct3D applications
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8.  
  9.  
  10. //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
  11. //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
  12.  
  13. using System;
  14. using Microsoft.DirectX;
  15. using Microsoft.DirectX.Direct3D;
  16. using Microsoft.Samples.DirectX.UtilityToolkit;
  17.  
  18. namespace CustomUISample
  19. {
  20.     /// <summary>CustomUI Sample Class</summary>
  21.     public class CustomUI : IFrameworkCallback, IDeviceCreation
  22.     {
  23.         #region Creation
  24.         /// <summary>Create a new instance of the class</summary>
  25.         public CustomUI(Framework f) 
  26.         { 
  27.             // Store framework
  28.             sampleFramework = f; 
  29.             // Create dialogs
  30.             hud = new Dialog(sampleFramework); 
  31.             sampleUi = new Dialog(sampleFramework); 
  32.         }
  33.         #endregion
  34.  
  35.         // Variables
  36.         private Framework sampleFramework = null; // Framework for samples
  37.         private Font statsFont = null; // Font for drawing text
  38.         private Sprite textSprite = null; // Sprite for batching text calls
  39.         private Effect effect = null; // D3DX Effect Interface
  40.         private ModelViewerCamera camera = new ModelViewerCamera(); // A model viewing camera
  41.         private Dialog hud = null; // dialog for standard controls
  42.         private Dialog sampleUi = null; // dialog for sample specific controls
  43.  
  44.         // Sample specific controls
  45.         private FrameworkMesh mesh = null; // Background mesh
  46.         private Matrix viewMatrix;
  47.  
  48.         // HUD Ui Control constants
  49.         private const int ToggleFullscreen = 1;
  50.         private const int ToggleReference = 3;
  51.         private const int ChangeDevice = 4;
  52.         // Sample UI Control constants
  53.         private const int EditBoxControl = 5;
  54.         private const int ComboBoxControl = 6;
  55.         private const int StaticControl = 7;
  56.         private const int OutputStaticControl = 8;
  57.         private const int SliderControl = 9;
  58.         private const int CheckBoxControl = 10;
  59.         private const int ClearEditControl = 11;
  60.         private const int RadioButton1A = 12;
  61.         private const int RadioButton1B = 13;
  62.         private const int RadioButton1C = 14;
  63.         private const int RadioButton2A = 15;
  64.         private const int RadioButton2B = 16;
  65.         private const int RadioButton2C = 17;
  66.         private const int ListBoxControl = 18;
  67.         private const int ListBoxControlMulti = 19;
  68.  
  69.         /// <summary>
  70.         /// Called during device initialization, this code checks the device for some 
  71.         /// minimum set of capabilities, and rejects those that don't pass by returning false.
  72.         /// </summary>
  73.         public bool IsDeviceAcceptable(Caps caps, Format adapterFormat, Format backBufferFormat, bool windowed)
  74.         {
  75.             // No fallback defined by this app, so reject any device that 
  76.             // doesn't support at least ps1.1
  77.             if (caps.PixelShaderVersion < new Version(1,1))
  78.                 return false;
  79.  
  80.             // Skip back buffer formats that don't support alpha blending
  81.             if (!Manager.CheckDeviceFormat(caps.AdapterOrdinal, caps.DeviceType, adapterFormat, 
  82.                 Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backBufferFormat))
  83.                 return false;
  84.  
  85.             return true;
  86.         }
  87.  
  88.         /// <summary>
  89.         /// This callback function is called immediately before a device is created to allow the 
  90.         /// application to modify the device settings. The supplied settings parameter 
  91.         /// contains the settings that the framework has selected for the new device, and the 
  92.         /// application can make any desired changes directly to this structure.  Note however that 
  93.         /// the sample framework will not correct invalid device settings so care must be taken 
  94.         /// to return valid device settings, otherwise creating the Device will fail.  
  95.         /// </summary>
  96.         public void ModifyDeviceSettings(DeviceSettings settings, Caps caps)
  97.         {
  98.             // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
  99.             // then switch to SWVP.
  100.             if ((!caps.DeviceCaps.SupportsHardwareTransformAndLight) ||
  101.                 (caps.VertexShaderVersion < new Version(1,1)))
  102.             {
  103.                 settings.BehaviorFlags = CreateFlags.SoftwareVertexProcessing;
  104.             }
  105.             else
  106.             {
  107.                 settings.BehaviorFlags = CreateFlags.HardwareVertexProcessing;
  108.             }
  109.  
  110.             // This application is designed to work on a pure device by not using 
  111.             // any get methods, so create a pure device if supported and using HWVP.
  112.             if ((caps.DeviceCaps.SupportsPureDevice) && 
  113.                 ((settings.BehaviorFlags & CreateFlags.HardwareVertexProcessing) != 0))
  114.                 settings.BehaviorFlags |= CreateFlags.PureDevice;
  115.  
  116.             // Debugging vertex shaders requires either REF or software vertex processing 
  117.             // and debugging pixel shaders requires REF.  
  118. #if(DEBUG_VS)
  119.             if (settings.DeviceType != DeviceType.Reference)
  120.             {
  121.                 settings.BehaviorFlags &= ~CreateFlags.HardwareVertexProcessing;
  122.                 settings.BehaviorFlags |= CreateFlags.SoftwareVertexProcessing;
  123.             }
  124. #endif
  125. #if(DEBUG_PS)
  126.             settings.DeviceType = DeviceType.Reference;
  127. #endif
  128.  
  129.         }
  130.  
  131.         /// <summary>
  132.         /// This event will be fired immediately after the Direct3D device has been 
  133.         /// created, which will happen during application initialization and windowed/full screen 
  134.         /// toggles. This is the best location to create Pool.Managed resources since these 
  135.         /// resources need to be reloaded whenever the device is destroyed. Resources created  
  136.         /// here should be released in the Disposing event. 
  137.         /// </summary>
  138.         private void OnCreateDevice(object sender, DeviceEventArgs e)
  139.         {
  140.             // Initialize the stats font
  141.             statsFont = ResourceCache.GetGlobalInstance().CreateFont(e.Device, 15, 0, FontWeight.Bold, 1, false, CharacterSet.Default,
  142.                 Precision.Default, FontQuality.Default, PitchAndFamily.FamilyDoNotCare | PitchAndFamily.DefaultPitch
  143.                 , "Arial");
  144.  
  145.             // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
  146.             // shader debugger. Debugging vertex shaders requires either REF or software vertex 
  147.             // processing, and debugging pixel shaders requires REF.  The 
  148.             // ShaderFlags.Force*SoftwareNoOptimizations flag improves the debug experience in the 
  149.             // shader debugger.  It enables source level debugging, prevents instruction 
  150.             // reordering, prevents dead code elimination, and forces the compiler to compile 
  151.             // against the next higher available software target, which ensures that the 
  152.             // unoptimized shaders do not exceed the shader model limitations.  Setting these 
  153.             // flags will cause slower rendering since the shaders will be unoptimized and 
  154.             // forced into software.  See the DirectX documentation for more information about 
  155.             // using the shader debugger.
  156.             ShaderFlags shaderFlags = ShaderFlags.None;
  157. #if(DEBUG_VS)
  158.             shaderFlags |= ShaderFlags.ForceVertexShaderSoftwareNoOptimizations;
  159. #endif
  160. #if(DEBUG_PS)
  161.             shaderFlags |= ShaderFlags.ForcePixelShaderSoftwareNoOptimizations;
  162. #endif
  163.             // Read the D3DX effect file
  164.             string path = Utility.FindMediaFile("CustomUI.fx");
  165.             effect = ResourceCache.GetGlobalInstance().CreateEffectFromFile(e.Device,
  166.                 path, null, null, shaderFlags, null);
  167.  
  168.             // Create the mesh
  169.             mesh = new FrameworkMesh(e.Device, "misc\\cell.x");
  170.  
  171.             // Setup the camera's view parameters
  172.             Vector3 eye = new Vector3(0.0f, 1.5f, -7.0f);
  173.             Vector3 at = new Vector3(0.0f, 0.2f, 0.0f);
  174.             camera.SetViewParameters(eye, at);
  175.             viewMatrix = Matrix.LookAtLH(eye, at, Camera.UpDirection);
  176.         }
  177.         
  178.         /// <summary>
  179.         /// This event will be fired immediately after the Direct3D device has been 
  180.         /// reset, which will happen after a lost device scenario. This is the best location to 
  181.         /// create Pool.Default resources since these resources need to be reloaded whenever 
  182.         /// the device is lost. Resources created here should be released in the OnLostDevice 
  183.         /// event. 
  184.         /// </summary>
  185.         private void OnResetDevice(object sender, DeviceEventArgs e)
  186.         {
  187.             SurfaceDescription desc = e.BackBufferDescription;
  188.             // Create a sprite to help batch calls when drawing many lines of text
  189.             textSprite = new Sprite(e.Device);
  190.  
  191.             // Setup the camera's projection parameters
  192.             float aspectRatio = (float)desc.Width / (float)desc.Height;
  193.             camera.SetProjectionParameters((float)Math.PI / 4, aspectRatio, 0.1f, 1000.0f);
  194.             camera.SetWindow(desc.Width, desc.Height);
  195.  
  196.             // Setup UI locations
  197.             hud.SetLocation(desc.Width-170, 0);
  198.             hud.SetSize(170,170);
  199.             sampleUi.SetLocation(0, 0);
  200.             sampleUi.SetSize(desc.Width, desc.Height);
  201.  
  202.             sampleUi.GetControl(StaticControl).SetLocation((desc.Width-200)/2, desc.Height-300);
  203.             sampleUi.GetControl(OutputStaticControl).SetSize(desc.Width - 170, desc.Height / 4);
  204.             sampleUi.GetControl(EditBoxControl).SetLocation(20, desc.Height - 270);
  205.             sampleUi.GetControl(EditBoxControl).SetSize(desc.Width - 40, 32);
  206.             sampleUi.GetControl(SliderControl).SetLocation(10, desc.Height - 140);
  207.             sampleUi.GetControl(CheckBoxControl).SetLocation(100, desc.Height - 50);
  208.             sampleUi.GetControl(ClearEditControl).SetLocation(100, desc.Height - 25);
  209.             sampleUi.GetControl(ComboBoxControl).SetLocation(20, desc.Height - 180);
  210.             sampleUi.GetControl(RadioButton1A).SetLocation(desc.Width - 140, 110);
  211.             sampleUi.GetControl(RadioButton1B).SetLocation(desc.Width - 140, 134);
  212.             sampleUi.GetControl(RadioButton1C).SetLocation(desc.Width - 140, 158);
  213.             sampleUi.GetControl(RadioButton2A).SetLocation(20, desc.Height - 100);
  214.             sampleUi.GetControl(RadioButton2B).SetLocation(20, desc.Height - 76);
  215.             sampleUi.GetControl(RadioButton2C).SetLocation(20, desc.Height - 52);
  216.             sampleUi.GetControl(ListBoxControl).SetLocation(desc.Width - 400, desc.Height - 180);
  217.             sampleUi.GetControl(ListBoxControl).SetSize(190, 96);
  218.             sampleUi.GetControl(ListBoxControlMulti).SetLocation(desc.Width - 200, desc.Height - 180);
  219.             sampleUi.GetControl(ListBoxControlMulti).SetSize(190, 124);
  220.         }
  221.  
  222.         /// <summary>
  223.         /// This event function will be called fired after the Direct3D device has 
  224.         /// entered a lost state and before Device.Reset() is called. Resources created
  225.         /// in the OnResetDevice callback should be released here, which generally includes all 
  226.         /// Pool.Default resources. See the "Lost Devices" section of the documentation for 
  227.         /// information about lost devices.
  228.         /// </summary>
  229.         private void OnLostDevice(object sender, EventArgs e)
  230.         {
  231.             if (textSprite != null)
  232.             {
  233.                 textSprite.Dispose();
  234.                 textSprite = null;
  235.             }
  236.         }
  237.  
  238.         /// <summary>
  239.         /// This callback function will be called once at the beginning of every frame. This is the
  240.         /// best location for your application to handle updates to the scene, but is not 
  241.         /// intended to contain actual rendering calls, which should instead be placed in the 
  242.         /// OnFrameRender callback.  
  243.         /// </summary>
  244.         public void OnFrameMove(Device device, double appTime, float elapsedTime)
  245.         {
  246.             // Update the camera's position based on user input 
  247.             camera.FrameMove(elapsedTime);
  248.  
  249.             Matrix m = Matrix.RotationY((float)Math.PI * elapsedTime / 40.0f);
  250.             viewMatrix = m * viewMatrix;
  251.         }
  252.  
  253.         /// <summary>
  254.         /// This callback function will be called at the end of every frame to perform all the 
  255.         /// rendering calls for the scene, and it will also be called if the window needs to be 
  256.         /// repainted. After this function has returned, the sample framework will call 
  257.         /// Device.Present to display the contents of the next buffer in the swap chain
  258.         /// </summary>
  259.         public void OnFrameRender(Device device, double appTime, float elapsedTime)
  260.         {
  261.             bool beginSceneCalled = false;
  262.  
  263.             // Clear the render target and the zbuffer 
  264.             device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x002D32AA, 1.0f, 0);
  265.             try
  266.             {
  267.                 device.BeginScene();
  268.                 beginSceneCalled = true;
  269.  
  270.                 // Update the effect's variables.  Instead of using strings, it would 
  271.                 // be more efficient to cache a handle to the parameter by calling 
  272.                 // Effect.GetParameter
  273.                 effect.SetValue("worldViewProjection", camera.WorldMatrix * viewMatrix * camera.ProjectionMatrix);
  274.                 effect.SetValue("worldMatrix", camera.WorldMatrix);
  275.                 effect.Technique = "RenderScene";
  276.  
  277.                 // Render the mesh
  278.                 int passes = effect.Begin(0);
  279.                 Mesh localMesh = mesh.LocalMesh;
  280.                 for (int pass = 0; pass < passes; pass++)
  281.                 {
  282.                     effect.BeginPass(pass);
  283.                     for(int i = 0; i < mesh.NumberMaterials; i++)
  284.                     {
  285.                         effect.SetValue("sceneTexture", mesh.GetTexture(i));
  286.                         effect.CommitChanges();
  287.                         localMesh.DrawSubset(i);
  288.                     }
  289.  
  290.                     effect.EndPass();
  291.                 }
  292.                 effect.End();
  293.  
  294.                 // Show frame rate
  295.                 RenderText();
  296.  
  297.                 // Show UI
  298.                 hud.OnRender(elapsedTime);
  299.                 sampleUi.OnRender(elapsedTime);
  300.             }
  301.             finally
  302.             {
  303.                 if (beginSceneCalled)
  304.                     device.EndScene();
  305.             }
  306.         }
  307.  
  308.         /// <summary>
  309.         /// Render the help and statistics text. This function uses the Font object for 
  310.         /// efficient text rendering.
  311.         /// </summary>
  312.         private void RenderText()
  313.         {
  314.             TextHelper txtHelper = new TextHelper(statsFont, textSprite, 15);
  315.  
  316.             // Output statistics
  317.             txtHelper.Begin();
  318.             txtHelper.SetInsertionPoint(5,5);
  319.             txtHelper.SetForegroundColor(System.Drawing.Color.Yellow);
  320.             txtHelper.DrawTextLine(sampleFramework.FrameStats);
  321.             txtHelper.DrawTextLine(sampleFramework.DeviceStats);
  322.  
  323.             txtHelper.SetForegroundColor(System.Drawing.Color.White);
  324.             txtHelper.DrawTextLine("Press ESC to quit.");
  325.             txtHelper.End();
  326.         }
  327.  
  328.         /// <summary>
  329.         /// Before handling window messages, the sample framework passes incoming windows 
  330.         /// messages to the application through this callback function. If the application sets 
  331.         /// noFurtherProcessing to true, the sample framework will not process the message
  332.         /// </summary>
  333.         public IntPtr OnMsgProc(IntPtr hWnd, NativeMethods.WindowMessage msg, IntPtr wParam, IntPtr lParam, ref bool noFurtherProcessing)
  334.         {
  335.             // Give the dialog a chance to handle the message first
  336.             noFurtherProcessing = hud.MessageProc(hWnd, msg, wParam, lParam);
  337.             if (noFurtherProcessing)
  338.                 return IntPtr.Zero;
  339.  
  340.             noFurtherProcessing = sampleUi.MessageProc(hWnd, msg, wParam, lParam);
  341.             if (noFurtherProcessing)
  342.                 return IntPtr.Zero;
  343.  
  344.             // Pass all remaining windows messages to camera so it can respond to user input
  345.             camera.HandleMessages(hWnd, msg, wParam, lParam);
  346.  
  347.             return IntPtr.Zero;
  348.         }
  349.  
  350.         /// <summary>
  351.         /// Initializes the application
  352.         /// </summary>
  353.         public void InitializeApplication()
  354.         {
  355.             int y = 10;
  356.             // Initialize the HUD
  357.             Button fullScreen = hud.AddButton(ToggleFullscreen,"Toggle full screen", 35, y, 125,22);
  358.             Button toggleRef = hud.AddButton(ToggleReference,"Toggle reference (F3)", 35, y += 24, 125,22);
  359.             Button changeDevice = hud.AddButton(ChangeDevice,"Change Device (F2)", 35, y += 24, 125,22);
  360.             // Hook the button events for when these items are clicked
  361.             fullScreen.Click += new EventHandler(OnFullscreenClicked);
  362.             toggleRef.Click += new EventHandler(OnRefClicked);
  363.             changeDevice.Click += new EventHandler(OnChangeDevicClicked);
  364.  
  365.             // Update some fonts
  366.             sampleUi.SetFont(1, "Comic Sans MS", 24, FontWeight.Normal);
  367.             sampleUi.SetFont(2, "Courier New", 16, FontWeight.Normal);
  368.  
  369.             // Now add the sample specific UI
  370.             y = 10;
  371.             sampleUi.AddStatic(StaticControl, "This is a static control.", 0, 0, 200, 30);
  372.             sampleUi.AddStatic(OutputStaticControl, "This static control provides feedback for your action.  It will change as you interact with the UI controls.",
  373.                 20, 50, 620, 300);
  374.             
  375.             sampleUi.GetStaticText(OutputStaticControl)[0].FontColor.States[(int)ControlState.Normal] = new ColorValue(0.0f, 1.0f, 0.0f, 1.0f); // Change color to green
  376.             sampleUi.GetStaticText(OutputStaticControl)[0].textFormat = DrawTextFormat.Left | DrawTextFormat.Top | DrawTextFormat.WordBreak;
  377.             sampleUi.GetStaticText(OutputStaticControl)[0].FontIndex = 1;
  378.  
  379.             // Edit box
  380.             EditBox edit = sampleUi.AddEditBox(EditBoxControl, "Edit control with default styles.  Type text here and press Enter.",
  381.                 20, 440, 600, 32);
  382.  
  383.             // Slider
  384.             Slider sl = sampleUi.AddSlider(SliderControl, 200, 450, 200, 24, 0, 1000, 500, false);
  385.  
  386.             // Check boxes
  387.             Checkbox hotKey = sampleUi.AddCheckBox(CheckBoxControl, "This is a checkbox with hotkey.  Press 'C' to toggle the check state.",
  388.                 150, 450, 350, 24, false, System.Windows.Forms.Keys.C, false);
  389.             Checkbox clearEdit = sampleUi.AddCheckBox(ClearEditControl, "This checkbox controls whether the edit control text is cleared when Enter is pressed.",
  390.                 150, 460, 430, 24, false);
  391.  
  392.             // Combo box
  393.             ComboBox combo = sampleUi.AddComboBox(ComboBoxControl, 0, 0, 200, 24);
  394.             if (combo != null)
  395.             {
  396.                 // Add some items
  397.                 combo.SetDropHeight(100);
  398.                 combo.AddItem("Combo box item", 0x11111111);
  399.                 combo.AddItem("Placeholder", 0x12121212);
  400.                 combo.AddItem("One more", 0x13131313);
  401.                 combo.AddItem("I can't get enough", 0x14141414);
  402.                 combo.AddItem("Ok, last one, I promise", 0x15151515);
  403.             }
  404.  
  405.             // Radio buttons
  406.             sampleUi.AddRadioButton(RadioButton1A, 1, "Radio group 1 Amy", 0, 50, 200, 24, false);
  407.             sampleUi.AddRadioButton(RadioButton1B, 1, "Radio group 1 Brian", 0, 50, 200, 24, false);
  408.             sampleUi.AddRadioButton(RadioButton1C, 1, "Radio group 1 Clark", 0, 50, 200, 24, false);
  409.  
  410.             sampleUi.AddRadioButton(RadioButton2A, 2, "Single", 0, 50, 70, 24, false);
  411.             sampleUi.AddRadioButton(RadioButton2B, 2, "Double", 0, 50, 70, 24, false);
  412.             sampleUi.AddRadioButton(RadioButton2C, 2, "Trouble", 0, 50, 70, 24, false);
  413.  
  414.             // List boxes
  415.             ListBox singleBox = sampleUi.AddListBox(ListBoxControl, 30, 400, 200, 150, ListBoxStyle.SingleSelection);
  416.             for (int i = 0; i < 15; i++)
  417.                 singleBox.AddItem("Single-selection listbox item " + i.ToString(), i);
  418.  
  419.             ListBox multiBox = sampleUi.AddListBox(ListBoxControlMulti, 30, 400, 200, 150, ListBoxStyle.Multiselection);
  420.             for (int i = 0; i < 30; i++)
  421.                 multiBox.AddItem("Multi-selection listbox item " + i.ToString(), i);
  422.  
  423.             // Hook some events
  424.             sl.ValueChanged += new EventHandler(OnValueChanged);
  425.             hotKey.Changed += new EventHandler(OnHotkeyBoxChanged);
  426.             clearEdit.Changed += new EventHandler(OnClearEditChanged);
  427.             combo.Changed += new EventHandler(OnComboChanged);
  428.             edit.Changed += new EventHandler(OnEditChanged);
  429.             edit.Enter += new EventHandler(OnEnterHit);
  430.             // All the radio buttons
  431.             sampleUi.GetRadioButton(RadioButton1A).Changed += new EventHandler(OnRadioButtonChanged);
  432.             sampleUi.GetRadioButton(RadioButton1B).Changed += new EventHandler(OnRadioButtonChanged);
  433.             sampleUi.GetRadioButton(RadioButton1C).Changed += new EventHandler(OnRadioButtonChanged);
  434.             sampleUi.GetRadioButton(RadioButton2A).Changed += new EventHandler(OnRadioButtonChanged);
  435.             sampleUi.GetRadioButton(RadioButton2B).Changed += new EventHandler(OnRadioButtonChanged);
  436.             sampleUi.GetRadioButton(RadioButton2C).Changed += new EventHandler(OnRadioButtonChanged);
  437.             // Finally the listboxes
  438.             singleBox.DoubleClick += new EventHandler(OnDoubleClick);
  439.             singleBox.Selection += new EventHandler(OnSingleSelection);
  440.             multiBox.DoubleClick += new EventHandler(OnDoubleClick);
  441.             multiBox.Selection += new EventHandler(OnMultiSelection);
  442.         }
  443.  
  444.         /// <summary>Called when the change device button is clicked</summary>
  445.         private void OnChangeDevicClicked(object sender, EventArgs e)
  446.         {
  447.             sampleFramework.ShowSettingsDialog(!sampleFramework.IsD3DSettingsDialogShowing);
  448.         }
  449.  
  450.         /// <summary>Called when the full screen button is clicked</summary>
  451.         private void OnFullscreenClicked(object sender, EventArgs e)
  452.         {
  453.             sampleFramework.ToggleFullscreen();
  454.         }
  455.  
  456.         /// <summary>Called when the ref button is clicked</summary>
  457.         private void OnRefClicked(object sender, EventArgs e)
  458.         {
  459.             sampleFramework.ToggleReference();
  460.         }
  461.  
  462.         /// <summary>Called when the slider value has changed</summary>
  463.         private void OnValueChanged(object sender, EventArgs e)
  464.         {
  465.             sampleUi.GetStaticText(OutputStaticControl).SetText
  466.                 ("You adjusted the slider control.\nThe new value reported is " + 
  467.                 (sender as Slider).Value.ToString());
  468.         }
  469.  
  470.         /// <summary>Called when the edit box has changed</summary>
  471.         private void OnEditChanged(object sender, EventArgs e)
  472.         {
  473.             EditBox eb = sender as EditBox;
  474.             sampleUi.GetStaticText(OutputStaticControl).SetText
  475.                 ("You changed the edit box control.\nThe new value is: \n" + 
  476.                 eb.Text.ToString());
  477.         }
  478.  
  479.         /// <summary>Called when the enter key has been hit on the edit box</summary>
  480.         private void OnEnterHit(object sender, EventArgs e)
  481.         {
  482.             EditBox eb = sender as EditBox;
  483.             sampleUi.GetStaticText(OutputStaticControl).SetText
  484.                 ("You have pressed Enter in the edit control.\nThe content of the edit control is:\n" + 
  485.                 eb.Text.ToString());
  486.  
  487.             // Clear the text if needed
  488.             if (sampleUi.GetCheckbox(ClearEditControl).IsChecked)
  489.                 eb.Text = string.Empty;
  490.         }
  491.  
  492.         /// <summary>Called when the slider value has changed</summary>
  493.         private void OnHotkeyBoxChanged(object sender, EventArgs e)
  494.         {
  495.             sampleUi.GetStaticText(OutputStaticControl).SetText(string.Format
  496.                 ("You {0} the upper check box.", (sender as Checkbox).IsChecked ? "checked" : "cleared"));
  497.         }
  498.  
  499.         /// <summary>Called when the slider value has changed</summary>
  500.         private void OnClearEditChanged(object sender, EventArgs e)
  501.         {
  502.             sampleUi.GetStaticText(OutputStaticControl).SetText(string.Format
  503.                 ("You {0} the upper check box.\nNow edit control will {1}", 
  504.                 (sender as Checkbox).IsChecked ? "checked" : "cleared",
  505.                 (sender as Checkbox).IsChecked ? "be cleared when you press Enter to send the text" 
  506.                 : "retain the text context when you press Enter to send the text"));
  507.         }
  508.  
  509.         /// <summary>Called when the combo box has changed</summary>
  510.         private void OnComboChanged(object sender, EventArgs e)
  511.         {
  512.             sampleUi.GetStaticText(OutputStaticControl).SetText(string.Format
  513.                 ("You selected a new item in the combox box.\nThe new item is {0} and the associated data is {1}", 
  514.                 (sender as ComboBox).GetSelectedItem().ItemText,
  515.                 ((int)(sender as ComboBox).GetSelectedItem().ItemData).ToString("x")));
  516.         }
  517.  
  518.         /// <summary>Called when the combo box has changed</summary>
  519.         private void OnRadioButtonChanged(object sender, EventArgs e)
  520.         {
  521.             RadioButton rb = sender as RadioButton;
  522.  
  523.             sampleUi.GetStaticText(OutputStaticControl).SetText(string.Format
  524.                 ("You selected a new radio button in the {0} radio group.\nThe new button is {1}", 
  525.                 (rb.ButtonGroup != 0) ? "UPPER" : "LOWER",
  526.                 rb.GetTextCopy()));
  527.         }
  528.  
  529.         /// <summary>Called when a listbox is double clicked</summary>
  530.         private void OnDoubleClick(object sender, EventArgs e)
  531.         {
  532.             ListBox lb = sender as ListBox;
  533.             ListBoxItem lbi = lb[lb.GetSelectedIndex(-1)];
  534.  
  535.             sampleUi.GetStaticText(OutputStaticControl).SetText(string.Format
  536.                 ("You double clicked an item in the {0} list box.\nThe item is {1}", 
  537.                 (lb.Style == ListBoxStyle.SingleSelection) ? "left" : "right",
  538.                 lbi.ItemText));
  539.         }
  540.  
  541.         /// <summary>Called when the a selection is made on the single listbox</summary>
  542.         private void OnSingleSelection(object sender, EventArgs e)
  543.         {
  544.             ListBox lb = sender as ListBox;
  545.             ListBoxItem lbi = lb[lb.GetSelectedIndex(-1)];
  546.  
  547.             sampleUi.GetStaticText(OutputStaticControl).SetText(string.Format
  548.                 ("You changed the selection in the left list box.\nThe item is {0}", 
  549.                 lbi.ItemText));
  550.         }
  551.  
  552.         /// <summary>Called when the a selection is made on the multi listbox</summary>
  553.         private void OnMultiSelection(object sender, EventArgs e)
  554.         {
  555.             ListBox lb = sender as ListBox;
  556.             int selectedIndex = -1;
  557.             string updatedText = "You changed the selection in the right list box.  The selected item(s) are\n";
  558.  
  559.             while ((selectedIndex = lb.GetSelectedIndex(selectedIndex)) != -1)
  560.             {
  561.                 updatedText += (selectedIndex.ToString() + ",");
  562.             }
  563.  
  564.             // Get rid of the last comma
  565.             updatedText = updatedText.Substring(0, updatedText.Length -1);
  566.             sampleUi.GetStaticText(OutputStaticControl).SetText(updatedText);
  567.         }
  568.  
  569.         /// <summary>
  570.         /// Entry point to the program. Initializes everything and goes into a message processing 
  571.         /// loop. Idle time is used to render the scene.
  572.         /// </summary>
  573.         static int Main() 
  574.         {
  575.             using(Framework sampleFramework = new Framework())
  576.             {
  577.                 CustomUI sample = new CustomUI(sampleFramework);
  578.                 // Set the callback functions. These functions allow the sample framework to notify
  579.                 // the application about device changes, user input, and windows messages.  The 
  580.                 // callbacks are optional so you need only set callbacks for events you're interested 
  581.                 // in. However, if you don't handle the device reset/lost callbacks then the sample 
  582.                 // framework won't be able to reset your device since the application must first 
  583.                 // release all device resources before resetting.  Likewise, if you don't handle the 
  584.                 // device created/destroyed callbacks then the sample framework won't be able to 
  585.                 // recreate your device resources.
  586.                 sampleFramework.DeviceLost += new EventHandler(sample.OnLostDevice);
  587.                 sampleFramework.DeviceCreated += new DeviceEventHandler(sample.OnCreateDevice);
  588.                 sampleFramework.DeviceReset += new DeviceEventHandler(sample.OnResetDevice);
  589.  
  590.                 sampleFramework.SetWndProcCallback(new WndProcCallback(sample.OnMsgProc));
  591.  
  592.                 sampleFramework.SetCallbackInterface(sample);
  593.                 try
  594.                 {
  595.  
  596.                     // Show the cursor and clip it when in full screen
  597.                     sampleFramework.SetCursorSettings(true, true);
  598.  
  599.                     // Initialize
  600.                     sample.InitializeApplication();
  601.  
  602.                     // Initialize the sample framework and create the desired window and Direct3D 
  603.                     // device for the application. Calling each of these functions is optional, but they
  604.                     // allow you to set several options which control the behavior of the sampleFramework.
  605.                     sampleFramework.Initialize(true, true, true); // Parse the command line, handle the default hotkeys, and show msgboxes
  606.                     sampleFramework.CreateWindow("CustomUI");
  607.                     sampleFramework.CreateDevice(0, true, Framework.DefaultSizeWidth, Framework.DefaultSizeHeight, 
  608.                         sample);
  609.  
  610.                     // Pass control to the sample framework for handling the message pump and 
  611.                     // dispatching render calls. The sample framework will call your FrameMove 
  612.                     // and FrameRender callback when there is idle time between handling window messages.
  613.                     sampleFramework.MainLoop();
  614.  
  615.                 }
  616. #if(DEBUG)
  617.                 catch (Exception e)
  618.                 {
  619.                     // In debug mode show this error (maybe - depending on settings)
  620.                     sampleFramework.DisplayErrorMessage(e);
  621. #else
  622.             catch
  623.             {
  624.                 // In release mode fail silently
  625. #endif
  626.                     // Ignore any exceptions here, they would have been handled by other areas
  627.                     return (sampleFramework.ExitCode == 0) ? 1 : sampleFramework.ExitCode; // Return an error code here
  628.                 }
  629.  
  630.                 // Perform any application-level cleanup here. Direct3D device resources are released within the
  631.                 // appropriate callback functions and therefore don't require any cleanup code here.
  632.                 return sampleFramework.ExitCode;
  633.             }
  634.         }
  635.     }
  636. }
  637.